package com.eastfair.messagecenter.util;

import cn.hutool.core.util.StrUtil;
//import com.baomidou.dynamic.datasource.annotation.DS;
import com.eastfair.constant.BusinessConstant;
import com.eastfair.core.base.R;
import com.eastfair.core.context.ContextUtil;
import com.eastfair.core.context.StaticContextUtil;
import com.eastfair.core.exception.BizException;
import com.eastfair.messagecenter.api.MsgServiceFeign;
import com.eastfair.messagecenter.dto.InnerSendDTO;
import com.eastfair.messagecenter.dto.SmsSendDTO;
import com.eastfair.messagecenter.enumeration.ChannelType;
import com.eastfair.messagecenter.model.InnerContentModel;
import com.eastfair.messagecenter.model.SmsContentModel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 * 业务实现类
 * 押金预警
 * </p>
 *
 * @author linan
 * @date 2023-02-14
 */
@Slf4j
@Service
//@DS("#thread.tenant")
public class SendMsgUtil {

    private static final String CONTENT = "content";

    @Resource
    private MsgServiceFeign msgServiceFeign;


    /**
     * 给全体用户立即发送站内信.
     *
     * @param content the content
     */
    public void sendInnerMsg(String content) {
        sendInnerMsg(content, StaticContextUtil.getProjectSystemScene());
    }

    /**
     * 给全体用户立即发送站内信.
     *
     * @param content     the content
     * @param systemScene the system scene
     */
    public void sendInnerMsg(String content, String systemScene) {
        sendInnerMsgByUserId(content, true, null, true, null, systemScene);
    }

    /**
     * 给指定用户立即发送站内信.
     *
     * @param content the content
     * @param userId  the user id
     */
    public void sendInnerMsgByUserId(String content, Long userId) {
        sendInnerMsgByUserId(content, userId, StaticContextUtil.getProjectSystemScene());
    }

    /**
     * 给指定用户立即发送站内信.
     *
     * @param content     the content
     * @param userId      the user id
     * @param systemScene the system scene
     */
    public void sendInnerMsgByUserId(String content, Long userId, String systemScene) {
        sendInnerMsgByUserId(content, false, userId, true, null, systemScene);
    }

    /**
     * 给指定用户按照预计时间发送站内信.
     *
     * @param content         内容
     * @param userId          接受用户ID
     * @param predictSendTime 预计发送时间
     */
    public void sendInnerMsgByUserId(String content, Long userId, LocalDateTime predictSendTime) {
        sendInnerMsgByUserId(content, userId, predictSendTime, StaticContextUtil.getProjectSystemScene());
    }

    /**
     * 给指定用户按照预计时间发送站内信.
     *
     * @param content         the content
     * @param userId          the user id
     * @param predictSendTime the predict send time
     * @param systemScene     the system scene
     */
    public void sendInnerMsgByUserId(String content, Long userId, LocalDateTime predictSendTime, String systemScene) {
        sendInnerMsgByUserId(content, false, userId, false, predictSendTime, systemScene);
    }

    /**
     * 给指定用户或全体用户立即发送或指定时间发送BUSINESS_COMMON类型站内信.
     *
     * @param content         内容
     * @param isSendAll       是否发送全体用户
     * @param userId          接受用户ID
     * @param predictSendTime 预计发送时间
     */
    public void sendInnerMsgByUserId(String content, Boolean isSendAll, Long userId, Boolean isSendNow, LocalDateTime predictSendTime) {
        sendInnerMsgByUserId(content, isSendAll, userId, isSendNow, predictSendTime, StaticContextUtil.getProjectSystemScene());
    }

    /**
     * 给指定用户或全体用户立即发送或指定时间发送BUSINESS_COMMON类型站内信.
     *
     * @param content         the content
     * @param isSendAll       the is send all
     * @param userId          the user id
     * @param isSendNow       the is send now
     * @param predictSendTime the predict send time
     * @param systemScene     the system scene
     */
    public void sendInnerMsgByUserId(String content, Boolean isSendAll, Long userId, Boolean isSendNow, LocalDateTime predictSendTime, String systemScene) {
        sendInnerMsgByUserIdOrAll(content, isSendAll, userId, isSendNow, predictSendTime, BusinessConstant.BUSINESS_COMMON, systemScene);
    }

    /**
     * 按照业务类型，给指定用户或全体用户立即发送或指定时间发送站内信.
     *
     * @param content         the content
     * @param isSendAll       the is send all
     * @param userId          the user id
     * @param isSendNow       the is send now
     * @param predictSendTime the predict send time
     * @param businessType    the business type
     */
    public void sendInnerMsgByUserIdOrAll(String content, Boolean isSendAll, Long userId, Boolean isSendNow, LocalDateTime predictSendTime, String businessType) {
        sendInnerMsgByUserIdOrAll(content, isSendAll, userId, isSendNow, predictSendTime, businessType, StaticContextUtil.getProjectSystemScene());
    }

    /**
     * 按照业务类型，给指定用户或全体用户立即发送或指定时间发送站内信.
     *
     * @param content         the content
     * @param isSendAll       the is send all
     * @param userId          the user id
     * @param isSendNow       the is send now
     * @param predictSendTime the predict send time
     * @param businessType    the business type
     * @param systemScene     the system scene
     */
    public void sendInnerMsgByUserIdOrAll(String content, Boolean isSendAll, Long userId, Boolean isSendNow, LocalDateTime predictSendTime, String businessType, String systemScene) {
        // 发送站内信
        InnerSendDTO innerSendDTO = new InnerSendDTO();
        innerSendDTO.setBusinessType(businessType);
        innerSendDTO.setChannelType(ChannelType.INNER_IM);
        innerSendDTO.setBusinessId(ContextUtil.getTrace());
        if (StrUtil.isNotBlank(systemScene)) {
            innerSendDTO.setSystemScene(systemScene);
        }
        innerSendDTO.setSystemScene(systemScene);
        InnerContentModel innerContentModel = new InnerContentModel();
        Map<String, Object> contentMap = new HashMap<>(16);
        contentMap.put(CONTENT, content);
        innerContentModel.setContentMap(contentMap);
        innerSendDTO.setInnerContentModelList(Collections.singletonList(innerContentModel));
        // 是否发送全体用户
        if (isSendAll) {
            innerSendDTO.setIsSendAll(true);
        } else {
            Set<Long> senUserIdList = new HashSet<>();
            senUserIdList.add(userId);
            innerSendDTO.setSenUserIdList(senUserIdList);
        }
        // 是否立即发送
        if (isSendNow) {
            innerSendDTO.setIsSendNow(BusinessConstant.YES);
        } else {
            // 发送时间
            innerSendDTO.setIsSendNow(BusinessConstant.NO);
            innerSendDTO.setPredictSendTime(predictSendTime);
        }
        sendInnerInMsg(innerSendDTO);
    }

    /**
     * 给指定团队的用户立即发送站内信.
     *
     * @param content the content
     * @param teamId  the team id
     */
    public void sendInnerMsgByTeamId(String content, Long teamId) {
        sendInnerMsgByTeamId(content, teamId, StaticContextUtil.getProjectSystemScene());
    }

    /**
     * 给指定团队的用户立即发送站内信.
     *
     * @param content     the content
     * @param teamId      the team id
     * @param systemScene the system scene
     */
    public void sendInnerMsgByTeamId(String content, Long teamId, String systemScene) {
        sendInnerMsgByTeamId(content, teamId, true, null, BusinessConstant.BUSINESS_COMMON, systemScene);
    }

    /**
     * 按照业务类型，给指定团队的用户立即发送或指定时间发送站内信.
     *
     * @param content         the content
     * @param teamId          the team id
     * @param isSendNow       the is send now
     * @param predictSendTime the predict send time
     * @param businessType    the business type
     */
    public void sendInnerMsgByTeamId(String content, Long teamId, Boolean isSendNow, LocalDateTime predictSendTime, String businessType) {
        sendInnerMsgByTeamId(content, teamId, isSendNow, predictSendTime, businessType, StaticContextUtil.getProjectSystemScene());
    }

    /**
     * 按照业务类型，给指定团队的用户立即发送或指定时间发送站内信.
     *
     * @param content         the content
     * @param teamId          the team id
     * @param isSendNow       the is send now
     * @param predictSendTime the predict send time
     * @param businessType    the business type
     * @param systemScene     the system scene
     */
    public void sendInnerMsgByTeamId(String content, Long teamId, Boolean isSendNow, LocalDateTime predictSendTime, String businessType, String systemScene) {
        // 发送站内信
        InnerSendDTO innerSendDTO = new InnerSendDTO();
        innerSendDTO.setBusinessType(businessType);
        innerSendDTO.setChannelType(ChannelType.INNER_IM);
        innerSendDTO.setBusinessId(ContextUtil.getTrace());
        if (StrUtil.isNotBlank(systemScene)) {
            innerSendDTO.setSystemScene(systemScene);
        }
        InnerContentModel innerContentModel = new InnerContentModel();
        Map<String, Object> contentMap = new HashMap<>(16);
        contentMap.put(CONTENT, content);
        innerContentModel.setContentMap(contentMap);
        innerSendDTO.setInnerContentModelList(Collections.singletonList(innerContentModel));
        // 发送给组织下的所有用户
        innerSendDTO.setIsSendAll(true);
        innerSendDTO.setTeamId(teamId);
        // 是否立即发送
        if (isSendNow) {
            innerSendDTO.setIsSendNow(BusinessConstant.YES);
        } else {
            // 发送时间
            innerSendDTO.setIsSendNow(BusinessConstant.NO);
            innerSendDTO.setPredictSendTime(predictSendTime);
        }
        sendInnerInMsg(innerSendDTO);
    }

    /**
     * 发送站内信.
     *
     * @param innerSendDTO the inner send dto
     */
    public void sendInnerInMsg(InnerSendDTO innerSendDTO) {
        log.info("sendInnerInMsg - 发送站内信, innerSendDTO={}", innerSendDTO);
        R result = msgServiceFeign.sendInnerInMsg(innerSendDTO);
        if (!result.getIsSuccess()) {
            log.error("sendInnerInMsg - 发送失败, result={}", result);
            throw BizException.wrap(result.getCode(), result.getMsg());
        }
        log.info("sendInnerInMsg - 发送站内信完成, result={}", result);
    }

    public void sendSms(Set<String> mobileSet, String context) {
        SmsSendDTO smsSendDTO = new SmsSendDTO();
        smsSendDTO.setBusinessType("BUSINESS_COMMON");
        smsSendDTO.setChannelType(ChannelType.SMS);
        smsSendDTO.setBusinessId(ContextUtil.getTrace());
        smsSendDTO.setMobileList(mobileSet);
        SmsContentModel smsContentModel = new SmsContentModel();
        Map<String, Object> contentMap = new HashMap<>();
        contentMap.put("content", context);
        smsContentModel.setContentMap(contentMap);
        smsSendDTO.setSmsContentModelList(Arrays.asList(smsContentModel));
        sendSmsInMsg(smsSendDTO);
    }
    public void sendSms(String mobile, String context) {
        SmsSendDTO smsSendDTO = new SmsSendDTO();
        smsSendDTO.setBusinessType("BUSINESS_COMMON");
        smsSendDTO.setChannelType(ChannelType.SMS);
        smsSendDTO.setBusinessId(ContextUtil.getTrace());
        Set<String> mobileSet = new HashSet<>();
        mobileSet.add(mobile);
        smsSendDTO.setMobileList(mobileSet);
        SmsContentModel smsContentModel = new SmsContentModel();
        Map<String, Object> contentMap = new HashMap<>();
        contentMap.put("content", context);
        smsContentModel.setContentMap(contentMap);
        smsSendDTO.setSmsContentModelList(Arrays.asList(smsContentModel));
        sendSmsInMsg(smsSendDTO);
    }

    /**
     * 发送短信
     *
     * @param smsSendDTO the inner send dto
     */
    public void sendSmsInMsg(SmsSendDTO smsSendDTO) {
        log.info("sendInnerInMsg - 发送短信, smsSendDTO={}", smsSendDTO);
        R result = msgServiceFeign.sendSmsMsg(smsSendDTO);
        if (!result.getIsSuccess()) {
            log.error("sendSmsMsg - 发送失败, result={}", result);
            throw BizException.wrap(result.getCode(), result.getMsg());
        }
        log.info("sendSmsMsg - 发送短信完成, result={}", result);
    }
}
